/*
 * @title: axios封装工具类
 * @author: andy.ten@tom.com & xukaixing@hotmail.com
 * @Date: 2022-03-21 16:52:35
 * @LastEditors: andy.ten@tom.com
 * @LastEditTime: 2022-06-06 13:17:39
 * @version: 1.0.8
 * @copyright: copyright (c) 2022 andyten
 *  node: you can not copy and/or use and/or modify this program free,
 *  please reserve the segment above.Please mail me if you have any question.
 */
import axios from 'axios';
import router from '@/router/routers';
import { getToken, getRefreshToken, getLoginAccount, getLoginUserId, getLoginUuid, getLanguage } from '@/utils/ht.auth';
import AppConfig from '@/appconfig';
import Hawthorn from 'hawthorn-ui/lib/hawthorn-ui.umd.min.js';
import store from '@/store';
// import Cookies from 'js-cookie';
const baseURL = AppConfig.gateWayUrl;
// 定义 http status code
const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队（异步任务）。',
  204: '删除数据成功。',
  400: '返回错误，请联系管理员。',
  401: '用户没有权限（令牌、用户名、密码错误）。',
  403: '用户得到授权，但是访问是被禁止的。',
  404: '未请求到指定的服务，请确认请求是否正确.',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除，且不会再得到的。',
  422: '当创建一个对象时，发生一个验证错误。',
  500: '服务器发生错误，请联系管理员.',
  502: '网关错误。',
  503: '服务不可用，请联系管理员.',
  504: '网关超时。',
  default: '网络链接错误，请检查网络.'
};

// 定义 gateway response status
const gatewayCodes = [23001, 23002, 23003, 23007, 23008, 1999];

/**
 * @todo: 设置请求header头部信息
 * @author: andy.ten@tom.com & xukaixing@hotmail.com
 * @Date: 2022-03-22 20:27:44
 */
const setHeaders = () => {
  return {
    Authorization: getToken(),
    AuthorizationRefresh: getRefreshToken(),
    useraccount: getLoginAccount(),
    userid: getLoginUserId(),
    loginuuid: getLoginUuid(),
    language: getLanguage(),
    userAgent: AppConfig.userAgent
  };
};
/**
 * @todo: 请求异常处理
 * @author: andy.ten@tom.com & xukaixing@hotmail.com
 * @Date: 2022-03-22 22:01:02
 * @param {*} error
 */
const errorHandler = (error) => {
  const { response = {}} = error;
  let status = 0;
  try {
    status = response.status;
  } catch (e) {
    if (error.toString().indexOf('TypeError:') !== -1) {
      Hawthorn.Notify.alert('请求参数不正确', 'error');
      return Promise.reject(error);
    }
    if (error.toString().indexOf('Error: timeout') !== -1) {
      Hawthorn.Notify.alert(`网络请求超时 ${response.status || ''}`, 'error');
      return Promise.reject(error);
    }

    if (error.toString().indexOf('Error: Network Error') !== -1) {
      Hawthorn.Notify.alert(`请求服务网络错误 ${response.status || ''}`, 'error');
      return Promise.reject(error);
    }
  }
  // bizException 自定义异常
  if (response.data && response.data.status === 'fail') {
    let errorMsg = '';
    if (response.status !== 400)
      errorMsg = codeMessage[status];
    Hawthorn.Notify.alert(`[${response.data.code || '[]'}] - ${errorMsg || response.data.message}`, 'error');
  } else
  if (status) {
    const errorMsg = codeMessage[status] || response.statusText || codeMessage['default'];
    switch (status) {
      case 401:
        // store.dispatch('user/LogOut').then(() => {
        // // 用户登录界面提示
        // // Cookies.set('point', 401)
        //   location.reload();
        // });
        Hawthorn.Notify.alert(`[${status || '[]'}] - ${errorMsg}`, 'error');
        break;
      case 403:
        router.push({ path: '/401' });
        break;
      default:
        Hawthorn.Notify.alert(`[${status || '[]'}] - ${errorMsg}`, 'error');
        break;
    }
  } else Hawthorn.Notify.alert(`请求无法响应 ${response.status || ''}`, 'error');

  // 设置loading block
  // store.dispatch('app/clearBtnLoading');
  return Promise.reject(error);
};

// 全局axios默认配置
// axios.defaults.baseURL = 'https://api.example.com';
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

// 创建axios实例
const service = axios.create({
  baseURL: process.env.NODE_ENV === 'production' ? process.env.VUE_APP_BASE_API : baseURL, // api 的 base_url
  timeout: AppConfig.requestTimeout, // 请求超时时间
  withCredentials: false
  // paramsSerializer: params => {
  //   // 序列化 GET 请求参数 -> a: [1, 2] => a=1&a=2
  //   return qs.stringify(params, { arrayFormat: 'repeat' });
  // }
});

// request拦截器
service.interceptors.request.use(
  (config) => {
  // 设置请求头部信息
    config.headers = {
      ...config.headers,
      ...setHeaders()
    };
    // 处理 POST 请求，参数是字符串，修正请求头 Content-Type 类型
    // 默认为：application/x-www-form-urlencoded
    if (config.method === 'post' && typeof config.data !== 'object')
      config.headers.post['Content-Type'] = 'application/json';

    // config.headers['Content-Type'] = 'application/json';

    // 设置loading block
    // if (config.mark) {
    //   store.dispatch('app/createBtnLoading', { [config.mark]: true });
    // }

    // 兼容 IE 缓存，增加随机数参数
    config.params = {
      ...(config.params || {}),
      _t: +new Date().getTime()
    };
    return config;
  }, errorHandler
);

// response 拦截器
service.interceptors.response.use(
  (response) => {
    const { headers, data, statusText, status } = response;
    const { datas } = data;
    let errMsg2;
    // store.dispatch('app/clearBtnLoading');
    var newToken = headers.newtoken;
    if (newToken)
      store.dispatch('user/refreshToken', newToken);

    if (status !== 200) {
      // 处理网关的响应
      if (gatewayCodes.includes(datas.code)) {
        try {
          errMsg2 = JSON.parse(datas.message);
        } catch (e) {
          errMsg2 = { 'error': datas.message };
        }
        //
        if (datas.code === 23003) {
          errMsg2 = '当前已退出登录，如需操作请重新登录。';
          // store.dispatch('app/createLogout');
          router.push({ path: '/' });
        }
        errMsg2 && Hawthorn.Notify.alert(errMsg2, 'error');
      } else {
        const code = datas.code;
        errMsg2 = codeMessage[code] || statusText || codeMessage['default'];
        switch (code) {
          case 401:
            // store.dispatch('LogOut').then(() => {
            //   // 用户登录界面提示
            //   //Cookies.set('point', 401)
            //   location.reload()
            // })
            break;
          case 403:
            // router.push({ path: '/401' })
            break;
          default:
            Hawthorn.Notify.alert(`${errMsg2} - ${status || ''}`, 'error');
            break;
        }
      }
      return Promise.reject(new Error(errMsg2));
    } else {
      // console.log(headers);
      if (data.status === 'fail') { // 成功 但是返回错误信息
        Hawthorn.Notify.alert(`${data.code || 'unknow'} - ${data.message || ''}`, 'error');
        return Promise.reject(new Error(data.message));
      }
      // 兼容blob下载出错json提示
      if (data instanceof Blob)
        // const reader = new FileReader();
        // reader.readAsText(data, 'utf-8');
        // reader.onload = function(e) {
        //   const errorMsg = JSON.parse(reader.result).message;
        //   Notify.alert(errorMsg, 'error');
        // };
        return { headers, data };
      else return response.data;
    }
  }, errorHandler);

export { setHeaders };
export default service;
